﻿using System;
using System.Collections;
using System.Web.Caching;

namespace NWebMock
{
    public interface ICache : IEnumerable
    {
        #region Properties

        /// <summary>
        /// Gets the number of items stored in the cache.
        /// </summary>
        int Count { get; }

        /// <summary>
        /// Gets the percentage of physical memory that can be consumed by an application before ASP.NET starts removing items from the cache.
        /// </summary>
        long EffectivePercentagePhysicalMemoryLimit { get; }

        /// <summary>
        /// Gets the number of bytes available for the cache.
        /// </summary>
        long EffectivePrivateBytesLimit { get; }

        /// <summary>
        /// Gets or sets the cache item at the specified key.
        /// </summary>
        /// <param name="key">A String object that represents the key for the cache item.</param>
        /// <returns>The specified cache item.</returns>
        Object this[string key] { get; set; }

        #endregion

        #region Methods

        /// <summary>
        /// Adds the specified item to the Cache object with dependencies, expiration and priority policies, and a delegate you can use to notify your application when the inserted item is removed from the Cache.
        /// </summary>
        /// <param name="key">The cache key used to reference the item.</param>
        /// <param name="value">The item to be added to the cache.</param>
        /// <param name="dependencies">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this parameter contains null.</param>
        /// <param name="absoluteExpiration">The time at which the added object expires and is removed from the cache. If you are using sliding expiration, the absoluteExpiration parameter must be NoAbsoluteExpiration.</param>
        /// <param name="slidingExpiration">The interval between the time the added object was last accessed and the time at which that object expires. If this value is the equivalent of 20 minutes, the object expires and is removed from the cache 20 minutes after it is last accessed. If you are using absolute expiration, the slidingExpiration parameter must be NoSlidingExpiration.</param>
        /// <param name="priority">The relative cost of the object, as expressed by the CacheItemPriority enumeration. The cache uses this value when it evicts objects; objects with a lower cost are removed from the cache before objects with a higher cost.</param>
        /// <param name="onRemoveCallback">A delegate that, if provided, is called when an object is removed from the cache. You can use this to notify applications when their objects are deleted from the cache.</param>
        /// <returns>An object that represents the item that was added if the item was previously stored in the cache; otherwise, null.</returns>
        Object Add(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);

        /// <summary>
        /// Retrieves the specified item from the Cache object.
        /// </summary>
        /// <param name="key">The identifier for the cache item to retrieve.</param>
        /// <returns>The retrieved cache item, or null if the key is not found.</returns>
        Object Get(string key);

        /// <summary>
        /// Retrieves a dictionary enumerator used to iterate through the key settings and their values contained in the cache.
        /// </summary>
        /// <returns>An enumerator to iterate through the Cache object.</returns>
        new IDictionaryEnumerator GetEnumerator();

        /// <summary>
        /// Inserts an item into the Cache object with a cache key to reference its location, using default values provided by the CacheItemPriority enumeration.
        /// </summary>
        /// <param name="key">The cache key used to reference the item.</param>
        /// <param name="value">The object to be inserted into the cache.</param>
        void Insert(string key, Object value);

        /// <summary>
        /// Inserts an object into the Cache that has file or key dependencies.
        /// </summary>
        /// <param name="key">The cache key used to identify the item.</param>
        /// <param name="value">The object to be inserted in the cache.</param>
        /// <param name="dependencies">The file or cache key dependencies for the inserted object. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this parameter contains null.</param>
        void Insert(string key, Object value, CacheDependency dependencies);

        /// <summary>
        /// Inserts an object into the Cache with dependencies and expiration policies.
        /// </summary>
        /// <param name="key">The cache key used to reference the object.</param>
        /// <param name="value">The object to be inserted in the cache.</param>
        /// <param name="dependencies">The file or cache key dependencies for the inserted object. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this parameter contains null.</param>
        /// <param name="absoluteExpiration">The time at which the inserted object expires and is removed from the cache. To avoid possible issues with local time such as changes from standard time to daylight saving time, use UtcNow rather than Now for this parameter value. If you are using absolute expiration, the slidingExpiration parameter must be NoSlidingExpiration.</param>
        /// <param name="slidingExpiration">The interval between the time the inserted object is last accessed and the time at which that object expires. If this value is the equivalent of 20 minutes, the object will expire and be removed from the cache 20 minutes after it was last accessed. If you are using sliding expiration, the absoluteExpiration parameter must be NoAbsoluteExpiration.</param>
        void Insert(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration);

        /// <summary>
        /// Inserts an object into the Cache object together with dependencies, expiration policies, and a delegate that you can use to notify the application before the item is removed from the cache.
        /// </summary>
        /// <param name="key">The cache key that is used to reference the object.</param>
        /// <param name="value">The object to insert into the cache.</param>
        /// <param name="dependencies">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this parameter contains null.</param>
        /// <param name="absoluteExpiration">The time at which the inserted object expires and is removed from the cache. To avoid possible issues with local time such as changes from standard time to daylight saving time, use UtcNow instead of Now for this parameter value. If you are using absolute expiration, the slidingExpiration parameter must be set to NoSlidingExpiration.</param>
        /// <param name="slidingExpiration">The interval between the time that the cached object was last accessed and the time at which that object expires. If this value is the equivalent of 20 minutes, the object will expire and be removed from the cache 20 minutes after it was last accessed. If you are using sliding expiration, the absoluteExpiration parameter must be set to NoAbsoluteExpiration.</param>
        /// <param name="onUpdateCallback">A delegate that will be called before the object is removed from the cache. You can use this to update the cached item and ensure that it is not removed from the cache.</param>
        void Insert(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemUpdateCallback onUpdateCallback);

        /// <summary>
        /// Inserts an object into the Cache object with dependencies, expiration and priority policies, and a delegate you can use to notify your application when the inserted item is removed from the Cache.
        /// </summary>
        /// <param name="key">The cache key used to reference the object.</param>
        /// <param name="value">The object to be inserted in the cache.</param>
        /// <param name="dependencies">The file or cache key dependencies for the item. When any dependency changes, the object becomes invalid and is removed from the cache. If there are no dependencies, this parameter contains null.</param>
        /// <param name="absoluteExpiration">The time at which the inserted object expires and is removed from the cache. To avoid possible issues with local time such as changes from standard time to daylight saving time, use UtcNow rather than Now for this parameter value. If you are using absolute expiration, the slidingExpiration parameter must be NoSlidingExpiration.</param>
        /// <param name="slidingExpiration">The interval between the time the inserted object was last accessed and the time at which that object expires. If this value is the equivalent of 20 minutes, the object will expire and be removed from the cache 20 minutes after it was last accessed. If you are using sliding expiration, the absoluteExpiration parameter must be NoAbsoluteExpiration.</param>
        /// <param name="priority">The cost of the object relative to other items stored in the cache, as expressed by the CacheItemPriority enumeration. This value is used by the cache when it evicts objects; objects with a lower cost are removed from the cache before objects with a higher cost.</param>
        /// <param name="onRemoveCallback">A delegate that, if provided, will be called when an object is removed from the cache. You can use this to notify applications when their objects are deleted from the cache.</param>
        void Insert(string key, Object value, CacheDependency dependencies, DateTime absoluteExpiration, TimeSpan slidingExpiration, CacheItemPriority priority, CacheItemRemovedCallback onRemoveCallback);

        /// <summary>
        /// Removes the specified item from the application's Cache object.
        /// </summary>
        /// <param name="key">A String identifier for the cache item to remove.</param>
        /// <returns>The item removed from the Cache. If the value in the key parameter is not found, returns null.</returns>
        Object Remove(string key);

        #endregion
    }
}
